package module

import (
	"encoding/json"
	"fmt"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"net/http"
)

type User struct {
	Username, Password, Sessionid string
	Avatar                        string
	Gender                        bool
}

func Http_userLogin(w http.ResponseWriter, r *http.Request) {
	defer requestLog(w, r)
	username := r.FormValue("username")
	password := r.FormValue("password")
	u, e := findUserByUsername(username)
	if e != nil {
		ReturnErr(w, e.Error(), 11)
		return
	}
	if u.Password != password {
		ReturnErr(w, "密码不正确", 12)
		return
	}
	u.Sessionid = NewToken()
	e = updateUser(u)
	if e != nil {
		ReturnErr(w, e.Error(), 13)
		return
	}
	ReturnInfo(w, u.Sessionid)
}
func Http_userRegister(w http.ResponseWriter, r *http.Request) {
	defer requestLog(w, r)
	username := r.FormValue("username")
	password := r.FormValue("password")
	gender := r.FormValue("gender")
	_, e := findUserByUsername(username)
	if e == nil {
		ReturnErr(w, "账号已存在", 14)
		return
	}
	if gender != "true" && gender != "false" {
		ReturnErr(w, "性别格式不正确", 15)
		return
	}
	sexual := true
	if gender == "false" {
		sexual = false
	}
	if !isUsernameOk(username) {
		ReturnErr(w, "用户名格式不正确", 16)
		return
	}
	if !isPasswordOk(password) {
		ReturnErr(w, "密码格式不正确", 17)
		return
	}
	u := User{
		Username:  username,
		Password:  password,
		Sessionid: NewToken(),
		Avatar:    getDefaultAvatarUrl(sexual),
		Gender:    sexual,
	}
	e = insertUser(u)
	if e != nil {
		ReturnErr(w, e.Error(), 18)
		return
	}
	ReturnInfo(w, u.Sessionid)
}
func Http_userChangePassword(w http.ResponseWriter, r *http.Request) {
	defer requestLog(w, r)
	username := r.FormValue("username")
	oldpassword := r.FormValue("oldpassword")
	newpassword := r.FormValue("newpassword")
	u, e := findUserByUsername(username)
	if e != nil {
		ReturnErr(w, e.Error(), 19)
		return
	}
	if u.Password != oldpassword {
		ReturnErr(w, "旧密码不正确", 110)
		return
	}
	if !isPasswordOk(newpassword) {
		ReturnErr(w, "新密码格式不正确", 111)
		return
	}
	u.Password = newpassword
	u.Sessionid = NewToken()
	e = updateUser(u)
	if e != nil {
		ReturnErr(w, e.Error(), 112)
		return
	}
	ReturnInfo(w, u.Sessionid)
}
func Http_userGet(w http.ResponseWriter, r *http.Request) {
	defer requestLog(w, r)
	username := r.FormValue("username")
	u, e := findUserByUsername(username)
	u.Password, u.Sessionid = "", ""
	if e != nil {
		ReturnErr(w, e.Error(), 113)
		return
	}
	data, e := json.Marshal(u)
	if e != nil {
		ReturnErr(w, e.Error(), 114)
		return
	}
	w.Write(data)
}
func getUserBySessionid(sessionid string) (User, error) {
	u := User{}
	s, e := mgo.Dial(mongodbServer)
	if e != nil {
		return u, e
	}
	defer s.Close()
	e = s.DB("fakenews").C("user").Find(bson.M{"sessionid": sessionid}).One(&u)
	return u, e
}
func getDefaultAvatarUrl(sexual bool) string {
	a := "boy.svg"
	if !sexual {
		a = "girl.svg"
	}
	return getCurrentAddr() + "res/img/" + a
}
func isUsernameOk(username string) bool {
	length := len(username)
	if username == "" || length > 10 {
		return false
	}
	return true
}
func isPasswordOk(password string) bool {
	length := len(password)
	if password == "" || length < 6 || length > 15 {
		return false
	}
	return true
}
func findUserByUsername(username string) (User, error) {
	u := User{}
	s, e := mgo.Dial(mongodbServer)
	if e != nil {
		fmt.Println("dial() failed:", e)
		return u, e
	}
	defer s.Close()
	e = s.DB("fakenews").C("user").Find(bson.M{"username": username}).One(&u)
	return u, e
}
func updateUser(u User) error {
	s, e := mgo.Dial(mongodbServer)
	if e != nil {
		return e
	}
	defer s.Close()
	e = s.DB("fakenews").C("user").Update(bson.M{"username": u.Username}, bson.M{
		"username":  u.Username,
		"password":  u.Password,
		"sessionid": u.Sessionid,
		"avatar":    u.Avatar,
		"gender":    u.Gender,
	})
	return e
}
func insertUser(u User) error {
	s, e := mgo.Dial(mongodbServer)
	if e != nil {
		return e
	}
	defer s.Close()
	e = s.DB("fakenews").C("user").Insert(&u)
	return e
}
